Tiny FORTRAN FORM ――――――――――――――――――――――――――――――――――――――― I/O 1980年 5、6、7、8、9月号掲載 MZ−80 マシン語 起動方法 モニタからロード ――――――――――――――――――――――――――――――――――――――― [1]FORMの概要 私達のかねてからの希望であった 『Tiny FORTRAN』コンパイラ『FORM』が完成したので、 これから数回にわたり、コンパイラの構成やアセンブルリストの説明を 述べていきたいと思います。 / FORM開発の理由  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 私達がFORTRANコンパイラの開発を計画したのは 以下の理由によります。 FORTRANは大学などで プログラミングの教育用に使われているし、 プログラミングの入門書には 必ずFORTRANが例に出されて説明されているなど、 初心者にも、比較的環解しやすいということ。 また、FORMはFORTRANのサブセットとして 仕様を小さく設計しているのでコンパイラそのものを理解し、 自分でコンパイラを設計・製作できるように、 その構造を発表し、 多くの方に使用してもらいたいということもあります。 ただ、マイコンの現状を見ると、 FORTRANの走るシステムは極めて少ないし、 これを走らせるためには 多くのハードウェアの助けを借りなければならないため、 コストがかかりすぎます。 幸い、MZ−80K/Cは ユーザーの自由になるメモリ空間が多く存在するので BASIC以外の言語を簡単に走らせやすいという特徴を持っているので、 今回もまた,このMZシステムを採用しました。 この、FORMを走らせるために必要なハードウェアは MZ−80K/Cだけで行なえるように設計しているので、 on memoryでコンパイルし 、実行するという形式を取っています。 / なぜコンパイラか  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ なぜ、コンパイラにしなければならないかというと、 FORTRANでは必要なところにしか文番号を付けないので、 interpritiveに実行するのは不可能であるというのがあります。 BASICではすべての行に文番号を付けるので、 不必要な文番号が付くという反面、 行の管理が簡単に行なえるので、インタープリタで充分実行可能になります。 また、BASICは皆さんも色々と使用して感じていると思いますが、 1行1行解釈して実行しているので実行時間が長いという欠点があります。 いままで発表してきたPALLはコンパイルといっても、 Tiny P−codeレベルのコンパイルなので、 コンパイラは非常にシンプルに作ることができるものの、 仮想スタック・マシンで実行するという、 形式的に見れば中間言語方式のため、 マシンコード・レベルのスピードが維持できません。 FORMでは、コンパイルしたオブジェクトは 完全にZ80のマシン語に展開し、 それのみで独立に動く、execute binaryを生成するので、 完全にマシン・レベルのスピードで動作します。 また、FORMはon memoryでコンパイルするために、 通常よく言われるような、リンケージ・エディタは存在せず、 リンク済みのサブルーチン・パッケージを用意して、 オブジェクトを生成していきます。 このため,FORMは1pass型コンパイラとして、 特異な構造を持っています。 テーブルは、構造上2つに分かれていて、 その内の1つを多重に使用することによって メモリ内で大幅なダイナミック・アロケーションを行ない、 コンパイル中はスーパーバイザがこのテーブルを管理しています。 / サブルーチンのリンク  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ サブルーチンのリンク方法は、通常のコンパイラの方法と異なっています。 普通、コンパイラはメイン・プログラム生成後にリンケージ・エディタが、 外部ファイル内に散在しているサブルーチン・パッケージを集めてきて、 後に付けるという方法が採られています。   サブルーチンのリンク方法  ・――――――・     ・――――――・  |      |     |      |  |      |     | SUB  |  | MAIN |     |      |  |      |     |――――――|  |――――――|     |      |←FORM  |      |←通常の |      |  |      | 方法  | MAIN |  | SUB  |     |      |  |      |     |      |  |      |     |      |  |      |     |      |  ・――――――・     ・――――――・ この構造はファイル操作を含むので、どうしても外部ファイルを必要とします。 私達はMZ用にH−DOSを開発し、この構造を実現できるコンパイラを開発中です。 つまリサブルーチンをリンケージするためには 外部ファイルが必要となるので本格的なDOSが必要とされるのです。 今回は外部ファイルを使用しないという条件なのでこの構造を変更し、 サブルーチン・パッケージを前に持ってきて、 あらかじめリンクしてしまう固定リンクの方法を取っています。 この方法は小システムでも実現でき、 コンパイラを簡素化するメリットがあります。 / コンパイラの勤き  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ コンパイラの動きを簡単に紹介しておきます。 詳しい説明は次回以降にします。 テキストがFORMの中に入るとコンパイルを始めます。 たとえば、A=B*CというTEXTがあるとします。 ・―――――――――――――――――――・ |                   | |  LD HL,(ADR-B)          | |  PUSH DE              | |  EX DE,HL            | |  LD HL,(ADR-C)          | |  CALL MULT             | |  POP DE              | |  LD (ADR-A),HL          | |                   | ・―――――――――――――――――――・ このテキストは上記のように式が展開されます。 ADR−A〜Cは別のルーチンで変数テーブルを作ってあるものとします。 まず、HLにBの内容を入れ、これをDEに移し、 またHLにCの内容を入れ、乗算のサブルーチンをCALLします。 このサブルーチンはHLとDEの乗算を行ない、結果をHLに残します。 最後にHLの内容をAに返してこの式の展開を終了します。 先ほど、『固定リンク』と述べたのは、 CALL MULTのアドレスがあらかじめテーブルで持ち、 そのアドレスを固定されているということです。 / FORMの予約語  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 変数は4文字まで付けることができます。 4文字以内は自由に付けることができますが、 FORMで使用している予約語を使うとエラーになります。 予約語は以下のとおりです。             FORMの予約語 ・――――――――――――――――――――――――――――――・ |(1)DIEMNSION (10)USR      (17)MEM  | |(2)GOTO      (11)DO       (18)MOD  | |(3)CALL      (12)CONTINUE (19)IOC  | |(4)IF        (13)RETURN   (20)ABS  | |(5)STOP      (14)SETG     (21)RND  | |(6)PAUSE     (15)RESG     (22)SIGN | |(7)BREAK     (16)END      (23)LOW  | |(8)READ                        | |(9)WRITE                       | ・――――――――――――――――――――――――――――――・ (1)〜(16)まではFORMで使用できるステートメントです。 ただ、FORTRANとFORMでは CALL、READ、WRITE、RETURNが 大幅に文法の違うところです。 (12)〜(23)まではファンクションです。 / FORM用エディタ  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ このFORMはこれ自身ではエディタ機能がないので、 コンパイルするソース・プログラム(text file)を 用意する必要があります。 このテキストはシャープから発売されている アセンブラ・テキストの中に入っている テキスト・エディタから出力される テキスト・ファイルと同等のものなので アセンブラをお持ちの方はこのエディタを使用してかまいません。 それ以外の方は、このエディタと同等のものを用意するか、 作るかしなければなりません。 私達はこのFORMをサポートするために、 エディタ、『ED−H』を用意しています。 ED−Hは、PASCALエディタを意識した 本格的2次元カーソルエディタで、 文番号なしのテキストを編集するように作られています。 現在これは、ディスク・ベースで動いているため、 カセット・バージョンに変更中です。  / テキスト・ファイル /  の構造  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ テキスト・ファイルの構造は、256バイトのブロックに分かれていて、 その中はASCIIコードの文字列です。 この文字列はODによって区切られています。   ―――  256  ―― ―――  256  ―― ――  |            |            |  ・――――――――――――――――――――――――――――――  |  |0D|  |0D|  |  |0D|  |0D|  |  ・―――――――――――――――――――――――――――――― エディタを作る方はこの構造になるように作ってください。 / FORMの使い方  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 最初にソース・プログラム(text)を テキスト・エディタで作り、カセットヘ出力します。 次に、FORMを入れ、テキストをロードします。 このときFORMはメモリ上にオブジェクトを生成します。 コンパイルが終了すると、実行型バイナリ・ファイルを外部へ出力します。 このバイナリ・ファイルをロードすると実行します。  ・――――・  |    |  |テキスト|テキスト・ファイル  |エディタ|――――・  |    |    |  ・――――・  ・――――・ オブジェクト ・―――――・          |    |        |     |          |FORM|―――――――→|MZ−80|          |    |        |     |          ・――――・        ・―――――・ したがって、完成したプログラムは 完全なマシン語プログラムとしての独立性を持ち、 実行時にはFORMは必要ありません。 このオブジェクトはマシンランゲージ・モニタでロードして 中を見ることもできます。 中を見るとテキストがどのように展開されているかが理解できると思います。  / コンパイル鋳の /  メモリ・マッフ  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ コンパイル時のメモリ・マップは以下のようになっています。    0000→・―――――――――・         |   ROM   | MZシステムROM    1000→|―――――――――|         | モニタ・ワーク |         | スタック    |    1200→|―――――――――|―・         |::::::::::::::::::| |         |::::FORM::::::| |         |::::システム::::::| |         |::::::::::::::::::| |         |―――――――――| |約6Kバイト         |         | |         |システム・ワーク | |         |         | |         |―――――――――| |         |OBJサブルーチン| |         |―――――――――|―・         |OBJ↓     |         |         |         |         |         |―――――――――|―・         |TBL NO.2 | |         |―――――――――| |―テーブル         |TBL NO.1 | |   RAMEND・―――――――――・―・ FORTRANはもともと科学技術計算用に作られた、 いわゆる高級言語です。 BASICももともとこのFORTRANから出ています。 BASICは文法的にはかなりFORTRANに似ていますが、 無駄な部分か多く、FORTRANの使いやすいところを 無視しているところがあります。 ただ、BASICは会話型なので、 エディットするときには簡単にできる特徴がありますが、 FORTRANはコンパイラのため、 ソース・レベルで修正しなければならないので手間が多くかかります。 しかし、バッチ処理でのデバッキングでは 会話型のBASICに比べてより能率的です。 これは、両者の使用条件によりユーザーが選択すべき問題でしょう。  / FORTRAN /  との違い  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ FORTRANとFORMの違いは、 メモリ制限および外部ファイルがないため、 サブルーチン・パッケ−ジを保存しにくく、 リンク作業が不可能なため、サブルーチン文などを削除し、 FORMATの必要性がマイコンにおいて非常に少ないので FORMATを削除して、READ、WRITE文に FORMAT的要素を含めました。 以上必要的にCALL文は、 BASICのGOSUB文と同等となっています。 それにともない、RETURN文も同一プログラム上に存在しています。 また、マイコンの特性を考えて、メモリの直接的操作を可能とし、 I/Omapped I/Oの入出力機能を持たせました。 / FORMの使用感  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ FORMは現在カセット・ベースなので、 これの使用感としては、現在シャープから出ているアセンブラの使用感と大差なく、 オフ・ライン処理のほとんどは、 ソース・プログラムの作成および、ソース・プログラムのデバッグのみとなります。 アセンブラと唯一違うところは、出力オブジェクトが実行型バイナリで、 即、実行可能な点にあります。  / ステートメントの /  簡単な説明(一部)  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ●DIMENSION  DIMENSIONの記述形式は一般FORTRANとフォーマットは同じです。  次元数は2次元までで、リミットは 255までです。  ただし、2次元において配列要素の数が 4,096以上になると  RAMエリアが極端に不足するため、エラーとして出力します。  配列の引数はFORTRANと異なり、  一般式が使用できます。  ただし、これは整数型のみです。  ・―――――――――――――――――――――――・  | [例] DIMENSION A(255)   |  |    DIMENSION B(10,10) |  |          :            |  |          :            |  ・―――――――――――――――――――――――・ ●IF  IF文はFORTRAN JIS 3000レベルと同等です。  つまり( )の中の式の結果により、  次項に続く文番号へ、−、0、+の順に飛び先ヘジャンプします。  ・―――――――――――――――――――――――・  | [例] IF(A−10)10,20,30   |  |        ↑       ↑      |  |        式      文番号     |  ・―――――――――――――――――――――――・ ●SETG(exp,exp) RESG(exp,exp)  MZの特徴であるセミグラフィックが使えるようにした命令です。  BASICのSET、RESETと同等です。  ・―――――――――――――――――――――――・  | ●SET                  |  | [例] SETG(X,Y)          |  |    SETG(A+C,B+D)      |  |        :              |  |        :              |  ・―――――――――――――――――――――――・  セミグラフィックをresetする場合は、RESGを使います。  ・―――――――――――――――――――――――・  | ●RESET                |  | [例] RESG(10,20)        |  |    RESG(A+D,B*C)      |  |        :              |  |        :              |  ・―――――――――――――――――――――――・  ( )の中は定数、変数、式が記述可能です。  MZの特徴であるセミグラフィック・モードがあるので、  これを高速性のあるコンパイラに組み込みたいという理由で  この命令を付けました。                   〔以下次号〕